package com.onenine.app.activity;

import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Looper;
import android.os.MessageQueue;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.view.SurfaceView;
import android.view.View;
import android.view.animation.Animation;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;

import com.faceunity.FURenderer;
import com.faceunity.effect.EffectBoardLayout;
import com.faceunity.effect.EffectDataMgr;
import com.faceunity.effect.MaskBoardLayout;
import com.faceunity.entity.Mask;
import com.onenine.app.R;
import com.onenine.app.event.GameMediaEvent;
import com.onenine.app.model.GameTargetJoin;
import com.onenine.app.utils.CDataProcessor;
import com.onenine.app.utils.DataType;
import com.onenine.app.utils.Permissions;
import com.onenine.app.view.DraggableLayout;
import com.onenine.base.utils.AnimHelper;
import com.onenine.base.utils.StatusBarUtils;
import com.onenine.common.util.Logger;
import com.onenine.dialog.CommonTextDialog;

import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.util.ArrayList;
import java.util.List;

import io.rong.calllib.IRongCallListener;
import io.rong.calllib.IVideoFrameListener;
import io.rong.calllib.RongCallClient;
import io.rong.calllib.RongCallCommon;
import io.rong.calllib.RongCallSession;
import io.rong.imlib.model.Conversation;
import pub.devrel.easypermissions.AppSettingsDialog;
import pub.devrel.easypermissions.EasyPermissions;

/**
 * 视频游戏中
 */
public class GameRunningVideoActivity extends GameRunningTextActivity
        implements EasyPermissions.PermissionCallbacks, IRongCallListener {

    private final int REQ_AUDIO_PERMISSION = 1;
    private String mCallId;
    private FrameLayout mLPreviewContainer;
    private DraggableLayout mSPreviewContainer;
    private SurfaceView mLocalVideo;
    private FrameLayout mEffectLayout;
    private boolean mEnableLocalVideo;
    private FURenderer mFURenderer;
    private boolean isInit;
    private boolean isDestroy;

    public static void launchActivity(Context context, String gameUrl
            , String roomId, String uid) {
        Intent intent = new Intent(context, GameRunningVideoActivity.class);
        intent.putExtra("gameUrl", gameUrl);
        intent.putExtra("roomId", roomId);
        intent.putExtra("uid", uid);
        context.startActivity(intent);
    }

    @Override
    protected int getLayout() {
        return R.layout.activity_game_running_video;
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        checkAudioPermissions();
        initFuEffect();
    }

    @Override
    protected void initViews() {
        super.initViews();
//        assistStatusBar();
        mEffectLayout = findViewById(R.id.inc_effect);
        mLPreviewContainer = findViewById(R.id.rc_voip_call_large_preview);
        mSPreviewContainer = findViewById(R.id.rc_voip_call_small_preview);
    }

    @Override
    protected void initListeners() {
        super.initListeners();
        mLPreviewContainer.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!TextUtils.isEmpty(getShownBoardTag())) {
                    onBackPressed();
                }
            }
        });
    }

    /**
     * 适应底部边距
     */
    private void assistStatusBar() {
        View vEffectBar = findViewById(R.id.inc_effect);
        RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) vEffectBar.getLayoutParams();
        lp.setMargins(0, 0, 0, StatusBarUtils.getNavigationBarHeight(this));
        vEffectBar.setLayoutParams(lp);
    }

    /**
     * 生成游戏web链接
     *
     * @param intent
     * @return
     */
    protected String getWebUrl(Intent intent) {
        String gameRunningUrl = String.format("%s?roomId=%s&uid=%s&scene=small"
                , intent.getStringExtra("gameUrl"), intent.getStringExtra("roomId")
                , intent.getStringExtra("uid"));
        Logger.e("游戏正在进行中：" + gameRunningUrl);
        return gameRunningUrl;
    }

    /**
     * 检查录音及相册权限
     */
    private void checkAudioPermissions() {
        if (!EasyPermissions.hasPermissions(this, Permissions.RECORD_AUDIO_CHAT_PERMISSIONS)) {
            EasyPermissions.requestPermissions(this, getString(R.string.permission_video_hint)
                    , REQ_AUDIO_PERMISSION, Permissions.RECORD_AUDIO_CHAT_PERMISSIONS);
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
    }

    @Override
    public void onPermissionsGranted(int requestCode, List<String> perms) {
    }

    @Override
    public void onPermissionsDenied(int requestCode, List<String> perms) {
        if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) {
            new AppSettingsDialog.Builder(this).setTitle(getString(R.string.permission_apply))
                    .setRationale(getString(R.string.permission_refuse_always_hint)).build().show();
        } else if (requestCode == REQ_AUDIO_PERMISSION) {
            finish();
        }
    }

    @Override
    protected void onTargetJoin(GameTargetJoin targetJoin) {
        super.onTargetJoin(targetJoin);
        if (targetJoin.getJoinIndex() == 1) {
            //目标对手先入者，向其发出视频通话
            convertUid2UserId(targetJoin.getUid(), new OnUid2UserIdResult() {
                @Override
                public void onConvert(String userId) {
                    startVideoCall(userId);
                }
            });
        }
    }

    @Override
    protected void onTargetLeave(GameTargetJoin targetLeave) {
        super.onTargetLeave(targetLeave);
        if (mCallId != null) {
            RongCallClient.getInstance().hangUpCall(mCallId);
        }
    }

    /**
     * 发起视频对话
     *
     * @param targetUseId
     */
    private void startVideoCall(String targetUseId) {
        RongCallClient.getInstance().setVoIPCallListener(this);
        RongCallClient.getInstance().startCall(Conversation.ConversationType.PRIVATE
                , targetUseId, new ArrayList<String>() {
                    {
                        add(targetUseId);
                    }
                }, null, RongCallCommon.CallMediaType.VIDEO, GAME_TAG);
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEvent(GameMediaEvent event) {
        if (RongCallCommon.CallMediaType.VIDEO == event.callMediaType) {
            RongCallClient.getInstance().setVoIPCallListener(this);
            RongCallClient.getInstance().acceptCall(event.callId);
        }
    }

    /**
     * 添加小窗口
     *
     * @param surfaceView
     */
    private void addSmallSurfaceView(SurfaceView surfaceView) {
        surfaceView.setZOrderOnTop(true);
        surfaceView.setZOrderMediaOverlay(true);
        mSPreviewContainer.addView(surfaceView);
        mSPreviewContainer.setVisibility(View.VISIBLE);
    }

    /**
     * 添加大窗口
     *
     * @param surfaceView
     */
    private void addLargeSurfaceView(SurfaceView surfaceView) {
        surfaceView.setZOrderOnTop(false);
        surfaceView.setZOrderMediaOverlay(false);
        mLPreviewContainer.addView(surfaceView);
        mLPreviewContainer.setVisibility(View.VISIBLE);
    }

    /**
     * 初始化视频特效
     */
    private void initFuEffect() {
        mFURenderer = new FURenderer
                .Builder(this)
                .inputTextureType(1)
                .createEGLContext(false)
                .needReadBackImage(false)
                .setNeedFaceBeauty(true)
                .defaultEffect(Mask.getDefaultMask())
                .build();
        //设置分辨率和帧数
        RongCallClient.getInstance().setVideoProfile(RongCallCommon.CallVideoProfile.VIDEO_PROFILE_480P_30F);
        RongCallClient.getInstance().registerVideoFrameListener(new IVideoFrameListener() {
            @Override
            public int processVideoFrame(int i, int i1, int i2) {
                if (isDestroy) {
                    return 0;
                }
                if (!isInit) {
                    mFURenderer.onSurfaceCreated();
                    isInit = true;
                }
                return mFURenderer.onDrawFrame(i2, i, i1);
            }
        });
    }

    @Override
    protected boolean useIndicatorEnable() {
        return false;
    }

    @Override
    public void onCallOutgoing(RongCallSession rongCallSession, SurfaceView surfaceView) {
        Logger.e("游戏视频通话已发送");
    }

    @Override
    public void onCallConnected(RongCallSession rongCallSession, SurfaceView localVideo) {
        Logger.e("游戏视频通话已连接");
        mCallId = rongCallSession.getCallId();
        mLocalVideo = localVideo;
    }

    @Override
    public void onCallDisconnected(RongCallSession rongCallSession, RongCallCommon.CallDisconnectedReason callDisconnectedReason) {
        Logger.e("游戏视频通话已断开");
        mCallId = rongCallSession.getCallId();
        mLPreviewContainer.removeAllViews();
        mSPreviewContainer.removeAllViews();
    }

    @Override
    public void onRemoteUserRinging(String s) {

    }

    @Override
    public void onRemoteUserJoined(String s, RongCallCommon.CallMediaType callMediaType, int i, SurfaceView remoteVideo) {
        Logger.e("游戏视频通话已加入");
        mLPreviewContainer.removeAllViews();
        addLargeSurfaceView(remoteVideo);
        mSPreviewContainer.removeAllViews();
        addSmallSurfaceView(mLocalVideo);
        mSPreviewContainer.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SurfaceView fromView = (SurfaceView) mSPreviewContainer.getChildAt(0);
                SurfaceView toView = (SurfaceView) mLPreviewContainer.getChildAt(0);
                mLPreviewContainer.removeAllViews();
                mSPreviewContainer.removeAllViews();
                addLargeSurfaceView(fromView);
                addSmallSurfaceView(toView);
            }
        });
    }

    @Override
    public void onRemoteUserInvited(String s, RongCallCommon.CallMediaType callMediaType) {

    }

    @Override
    public void onRemoteUserLeft(String s, RongCallCommon.CallDisconnectedReason callDisconnectedReason) {

    }

    @Override
    public void onMediaTypeChanged(String s, RongCallCommon.CallMediaType callMediaType, SurfaceView surfaceView) {

    }

    @Override
    public void onError(RongCallCommon.CallErrorCode callErrorCode) {

    }

    @Override
    public void onRemoteCameraDisabled(String s, boolean b) {

    }

    @Override
    public void onWhiteBoardURL(String s) {

    }

    @Override
    public void onNetworkReceiveLost(int i) {

    }

    @Override
    public void onNetworkSendLost(int i) {

    }

    @Override
    public void onNotifySharingScreen(String s, boolean b) {

    }

    @Override
    public void onNotifyDegradeNormalUserToObserver(String s) {

    }

    @Override
    public void onNotifyAnswerObserverRequestBecomeNormalUser(String s, long l) {

    }

    @Override
    public void onNotifyUpgradeObserverToNormalUser() {

    }

    @Override
    public void onNotifyHostControlUserDevice(String s, int i, int i1) {

    }

    @Override
    public void onNotifyAnswerUpgradeObserverToNormalUser(String s, SurfaceView surfaceView) {

    }

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.btn_quit) {
            onHangupBtnClick(v);
        } else {
            super.onClick(v);
        }
    }

    /**
     * 挂断退出
     *
     * @param view
     */
    public void onHangupBtnClick(View view) {
        new CommonTextDialog.Builder(this)
                .setText(R.string.video_game_chat_quit_hint)
                .setCancelOutside(true)
                .setOnOkClickListener(new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        finish();
                    }
                }).builder().show();
    }

    /**
     * 隐藏道具显示操作按钮
     */
    public void dismissMaskBoard(View view) {
        View operView = findViewById(R.id.rl_operate_button);
        dismissOperationButtonsAnim(view, new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {

            }

            @Override
            public void onAnimationEnd(Animation animation) {
                view.setVisibility(View.GONE);
                showMaskBoardLayoutAnim(operView);
            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });
    }

    /**
     * 显示道具面板
     *
     * @param view
     */
    public void onShowMaskBoard(View view) {
        CDataProcessor.getEffectData(DataType.EFFECT_MASK);
        CDataProcessor.getEffectData(DataType.EFFECT_GESTURE);
        View actionView = findViewById(R.id.rl_operate_button);
        MaskBoardLayout maskBoardLayout = findViewById(R.id.mask_board_layout);
        EffectBoardLayout beautyLayout = findViewById(R.id.beauty_board_layout);
        beautyLayout.setVisibility(View.GONE);
        EffectBoardLayout filterLayout = findViewById(R.id.filter_board_layout);
        filterLayout.setVisibility(View.GONE);
        maskBoardLayout.setOnFUControlListener(mFURenderer);
        dismissOperationButtonsAnim(actionView, new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {

            }

            @Override
            public void onAnimationEnd(Animation animation) {
                actionView.setVisibility(View.GONE);
                showMaskBoardLayoutAnim(maskBoardLayout);
            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });
    }

    /**
     * 显示美颜面板
     *
     * @param view
     */
    public void onShowBeautyBoard(View view) {
        View actionView = findViewById(R.id.rl_operate_button);
        MaskBoardLayout maskBoardLayout = findViewById(R.id.mask_board_layout);
        maskBoardLayout.setVisibility(View.GONE);
        EffectBoardLayout beautyLayout = findViewById(R.id.beauty_board_layout);
        beautyLayout.setTypeOnFuListener(EffectBoardLayout.BEAUTY_TYPE, mFURenderer);
        EffectBoardLayout filterLayout = findViewById(R.id.filter_board_layout);
        filterLayout.setVisibility(View.GONE);
        dismissOperationButtonsAnim(actionView, new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {

            }

            @Override
            public void onAnimationEnd(Animation animation) {
                actionView.setVisibility(View.GONE);
                showMaskBoardLayoutAnim(beautyLayout);
            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });
    }

    /**
     * 显示美颜面板
     *
     * @param view
     */
    public void onShowFilterBoard(View view) {
        View actionView = findViewById(R.id.rl_operate_button);
        MaskBoardLayout maskBoardLayout = findViewById(R.id.mask_board_layout);
        maskBoardLayout.setVisibility(View.GONE);
        EffectBoardLayout beautyLayout = findViewById(R.id.beauty_board_layout);
        beautyLayout.setVisibility(View.GONE);
        EffectBoardLayout filterLayout = findViewById(R.id.filter_board_layout);
        filterLayout.setTypeOnFuListener(EffectBoardLayout.FILTER_TYPE, mFURenderer);
        dismissOperationButtonsAnim(actionView, new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {

            }

            @Override
            public void onAnimationEnd(Animation animation) {
                actionView.setVisibility(View.GONE);
                showMaskBoardLayoutAnim(filterLayout);
            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });
    }

    /**
     * 隐藏底部操作按钮组
     */
    private void dismissOperationButtonsAnim(View view, Animation.AnimationListener animationListener) {
        AnimHelper.offTranslateAnimDismissToBottom(view, animationListener);
    }

    /**
     * 显示道具面板
     */
    private void showMaskBoardLayoutAnim(View view) {
        Looper.myQueue().addIdleHandler(new MessageQueue.IdleHandler() {
            @Override
            public boolean queueIdle() {
                view.setVisibility(View.VISIBLE);
                AnimHelper.offTranslateAnimShowFromBottom(view);
                return false;
            }
        });
    }

    public void onLocalVideoEnableClick(View view) {
//        RongCallClient.getInstance().changeCallMediaType(RongCallCommon.CallMediaType.AUDIO);
//        callSession.setMediaType(RongCallCommon.CallMediaType.AUDIO);
//        initAudioCallView();
        mEnableLocalVideo = !mEnableLocalVideo;
        RongCallClient.getInstance().setEnableLocalVideo(mEnableLocalVideo);
    }

    @Override
    public void onBackPressed() {
        String showTag = getShownBoardTag();
        if (TextUtils.isEmpty(showTag)) {
            super.onBackPressed();
        } else {
            dismissMaskBoard(mEffectLayout.findViewWithTag(showTag));
        }
    }

    /**
     * 获取显示面板tag
     *
     * @return
     */
    private String getShownBoardTag() {
        MaskBoardLayout maskBoardLayout = findViewById(R.id.mask_board_layout);
        if (maskBoardLayout.getVisibility() == View.VISIBLE) {
            return maskBoardLayout.getTag().toString();
        }
        EffectBoardLayout beautyLayout = findViewById(R.id.beauty_board_layout);
        if (beautyLayout.getVisibility() == View.VISIBLE) {
            return beautyLayout.getTag().toString();
        }
        EffectBoardLayout filterLayout = findViewById(R.id.filter_board_layout);
        if (filterLayout.getVisibility() == View.VISIBLE) {
            return filterLayout.getTag().toString();
        }
        return "";
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        isDestroy = true;
        RongCallClient.getInstance().hangUpCall();
        if (mFURenderer != null) {
            RongCallClient.getInstance().unregisterVideoFrameObserver();
            mFURenderer.onFilterNameSelected(EffectDataMgr.getInstance().getOriginFilter());
            mFURenderer.onSurfaceDestroyed();
        }
    }

}
